package main

import (
	"hg.cloud9lib.net/cloud9lib.hg/index"
	"hg.cloud9lib.net/cloud9lib.hg/rest"
	"hg.cloud9lib.net/cloud9lib.hg/sync"
	"flag"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
)

func onUpdate(pattern string) {

	dest, err := index.Route(pattern)

	if err != nil {
		log.Println(err)
	}

	desturl, err := url.Parse(dest)

	if err != nil {
		log.Println(err)
	}

	log.Println("routed: added route ", pattern, desturl.String())
	http.Handle(pattern, rest.Log(httputil.NewSingleHostReverseProxy(desturl)))
}

func tryRedirect(w http.ResponseWriter, req *http.Request) {

	if strings.HasPrefix(req.Host, "www.") || req.Host == "" {

		log.Println("routed: not found " + req.URL.String())
		http.NotFoundHandler()
		return
	}

	log.Println("routed: trying redirect to www from " + req.Host)
	http.Redirect(w, req, "http://www."+req.Host, 303)
}

func main() {

	// if router and index are not on the same host, the router must be told where index is
	indexurl := flag.String("index", "http://localhost:8006", "local URL of the index server--must not require routing")
	cert := flag.String("cert", "cert.pem", "https certificate file")
	key := flag.String("key", "key.pem", "https key file")

	flag.Parse()

	rest.LogPrefix = "routed: "

	feed := sync.Feed(*indexurl, "routes")
	go feed.Subscribe(0, nil, onUpdate)

	http.HandleFunc("/", tryRedirect)

	go func () {
		err := http.ListenAndServeTLS(":443", *cert, *key, nil)
		panic(err)
	} ()

	err := http.ListenAndServe(":80", nil)

	panic(err)
}
